package cn.hiapi.shop.api;

import cn.hiapi.basic.ResponseEntity;
import cn.hiapi.basic.controller.BasicController;
import cn.hiapi.basic.enums.ResponseCode;
import cn.hiapi.basic.jpa.pageable.QueryWrapper;
import cn.hiapi.basic.security.TokenGet;
import cn.hiapi.basic.token.Token;
import cn.hiapi.basic.token.enums.TokenType;
import cn.hiapi.interfaces.DispatchContext;
import cn.hiapi.interfaces.config.IParamsService;
import cn.hiapi.interfaces.config.data.ParamsData;
import cn.hiapi.interfaces.finance.IAssetsService;
import cn.hiapi.interfaces.finance.model.AmountModel;
import cn.hiapi.interfaces.system.ILocationService;
import cn.hiapi.interfaces.system.data.LocationData;
import cn.hiapi.shop.api.user.request.ApplyShopRequest;
import cn.hiapi.shop.entity.shop.*;
import cn.hiapi.shop.service.category.GoodsCategoryService;
import cn.hiapi.shop.service.shop.*;
import cn.hiapi.shop.vo.ShopAccount;
import cn.hiapi.shop.vo.ShopBase;
import cn.hiapi.shop.vo.ShopInfoVo;
import cn.hiapi.shopkeeper.consts.AppConst;
import cn.hiapi.shopkeeper.enums.OrderStatus;
import cn.hiapi.shopkeeper.service.order.ActivityOrderService;
import cn.hiapi.user.entity.User;
import cn.hiapi.utils.JsonUtils;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author AdinZ
 * @date 2022/12/12 20:57
 */
@RestController("shopkeeperShopController")
@RequestMapping("/shop")
@Api(tags = "商家端")
@Secured(TokenType.ROLE_USER)
public class ShopController extends BasicController {
    private final DispatchContext dispatchContext;

    public ShopController(DispatchContext dispatchContext) {
        this.dispatchContext = dispatchContext;
    }


    @ApiOperation(value = "我管理的店铺", notes = "我管理的店铺", nickname = "AdinZ")
    @GetMapping("/list")
    public ResponseEntity<List<ShopBase>> list() {
        List<ShopLinkUser> linkUsers = this.dispatchContext.getServiceOne(ShopLinkUserService.class)
                .findList(new QueryWrapper().eq("uid", TokenGet.get().getFid()));
        if (linkUsers.isEmpty()) return toSuccess(Lists.newArrayList());
        List<Long> collect = linkUsers.stream().map(ShopLinkUser::getShopId).collect(Collectors.toList());
        List<Shop> shops = this.dispatchContext.getServiceOne(ShopService.class).findList(collect);
        if (shops.isEmpty()) return toSuccess(Lists.newArrayList());

        List<ShopBase> list = shops.stream().filter(e -> e.getStatus() == 1).map(e -> e.copy(new ShopBase())).collect(Collectors.toList());
        return toSuccess(list);
    }


    @ApiOperation(value = "店铺首页", notes = "店铺首页", nickname = "AdinZ")
    @GetMapping("/info")
    public ResponseEntity<ShopInfoVo> shopInfo(@RequestParam("shopId") long shopId) {
        Token<User> token = TokenGet.get();
        final ShopLinkUser linkUser = this.dispatchContext.getServiceOne(ShopLinkUserService.class).verifyShop(token.getFid(), shopId);
        Shop shop = this.dispatchContext.getServiceOne(ShopService.class).get(shopId);
        if (shop == null) return toError(ResponseCode.SHOP_EXISTS);
        ShopInfoVo vo = shop.copy(new ShopInfoVo());

        List<Shop> list = this.dispatchContext.getServiceOne(ShopService.class).findList(new QueryWrapper().eq("mid", shop.getId())
                .eq("type", 10));


        LocationData locationData = this.dispatchContext.getServiceOne(ILocationService.class).locationGet(shop.getStateId());
        if (locationData != null) vo.setState(locationData.getName());
        locationData = this.dispatchContext.getServiceOne(ILocationService.class).locationGet(shop.getCityId());
        if (locationData != null) vo.setCity(locationData.getName());
        locationData = this.dispatchContext.getServiceOne(ILocationService.class).locationGet(shop.getDistrictId());
        if (locationData != null) vo.setDistrict(locationData.getName());
        User user = token.getData();
        ShopAccount account = new ShopAccount();
        account.setAvatar(user.getAvatar());
        account.setNickname(user.getNickname());
        account.setMobile(user.getMobile());
        ShopAccountRole role = this.dispatchContext.getServiceOne(ShopAccountRoleService.class).get(linkUser.getRid());
        if (role != null) {
            account.setRoleName(role.getName());
            account.setRoleType(role.getType());
        }
        List<ParamsData> paramsData = this.dispatchContext.getServiceOne(IParamsService.class).findByFid(shop.getId());
        JSONObject object = ParamsData.toJson(paramsData);
        vo.setOther(object);
        vo.setImages(StringUtils.split(shop.getThumbs(), ","));
        vo.setLicenses(StringUtils.split(shop.getLicensePics(), ","));
        ShopType shopType = this.dispatchContext.getServiceOne(ShopTypeService.class).get(shop.getCid());
        if (shopType != null) vo.setCategory(shopType.getName());

        if (list.size() > 0) {
            Shop s = list.get(0);
            s.copy(vo);
            vo.setId(shop.getId());
            locationData = this.dispatchContext.getServiceOne(ILocationService.class).locationGet(s.getStateId());
            if (locationData != null) vo.setState(locationData.getName());
            locationData = this.dispatchContext.getServiceOne(ILocationService.class).locationGet(s.getCityId());
            if (locationData != null) vo.setCity(locationData.getName());
            locationData = this.dispatchContext.getServiceOne(ILocationService.class).locationGet(s.getDistrictId());
            if (locationData != null) vo.setDistrict(locationData.getName());
            paramsData = this.dispatchContext.getServiceOne(IParamsService.class).findByFid(s.getId());
            object = ParamsData.toJson(paramsData);
            vo.setOther(object);
            vo.setImages(StringUtils.split(s.getThumbs(), ","));
            vo.setLicenses(StringUtils.split(s.getLicensePics(), ","));

            shopType = this.dispatchContext.getServiceOne(ShopTypeService.class).get(s.getCid());
            if (shopType != null) vo.setCategory(shopType.getName());
        }
        ShopScore score = this.dispatchContext.getServiceOne(ShopScoreService.class).getByShopId(shop.getMid(), shop.getId());
        vo.setScore(score != null ? score.getComplexScore() : BigDecimal.ZERO);

        return toSuccess(vo);
    }


    @ApiOperation(value = "我的面板数据", notes = "我的面板数据", nickname = "AdinZ")
    @GetMapping("/dashboard")
    public ResponseEntity dashboard(@RequestParam("shopId") long shopId) {
        Token<User> token = TokenGet.get();
        ShopLinkUser linkUser = this.dispatchContext.getServiceOne(ShopLinkUserService.class).verifyShop(token.getFid(), shopId);
        long waitPay = this.dispatchContext.getServiceOne(ActivityOrderService.class).count(new QueryWrapper().eq("status", OrderStatus.WAIT_PAY).eq("shopId", shopId));
        long waitCheck = this.dispatchContext.getServiceOne(ActivityOrderService.class).count(new QueryWrapper().eq("status", OrderStatus.WAIT_USE).eq("shopId", shopId));
        long comment = this.dispatchContext.getServiceOne(ActivityOrderService.class).count(new QueryWrapper().eq("status", OrderStatus.WAIT_COMMENT).eq("shopId", shopId));
        List<AmountModel> assets = this.dispatchContext.getServiceOne(IAssetsService.class).findAssets(shopId);
        Optional<AmountModel> moneyOptional = assets.stream().filter(e -> StringUtils.equalsIgnoreCase(e.getAmountType(), AppConst.FINANCE_AMOUNT_MONEY)).findFirst();
        Optional<AmountModel> sugarOptional = assets.stream().filter(e -> StringUtils.equalsIgnoreCase(e.getAmountType(), AppConst.FINANCE_AMOUNT_SUGAR)).findFirst();
        Shop shop = this.dispatchContext.getServiceOne(ShopService.class).get(shopId);
        ShopScore score = this.dispatchContext.getServiceOne(ShopScoreService.class).getByShopId(shop.getMid(), shop.getId());
        return toSuccess(JsonUtils.builder()
                .put("order", JsonUtils.builder()
                        .put("waitPay", waitPay)
                        .put("waitCheck", waitCheck)
                        .put("comment", comment)
                        .build())
                .put("balance", JsonUtils.builder()
                        .put(AppConst.FINANCE_AMOUNT_MONEY, moneyOptional.isPresent() ? moneyOptional.get().getAmount() : 0)
                        .put(AppConst.FINANCE_AMOUNT_SUGAR, sugarOptional.isPresent() ? sugarOptional.get().getAmount() : 0)
                        .build())
                .put("info", JsonUtils.builder()
                        .put("logo", shop.getLogo())
                        .put("name", shop.getName())
                        .put("role", linkUser.getRid())
                        .put("score", score != null ? score.getComplexScore() : 0)
                        .build())
                .build());
    }


    @ApiOperation(value = "修改店铺资料", notes = "修改店铺资料", nickname = "AdinZ")
    @PostMapping("/edit-shop")
    public ResponseEntity editShop(@RequestBody ApplyShopRequest request) {
        this.dispatchContext.getServiceOne(ShopLinkUserService.class).verifyShop(TokenGet.get().getFid(), request.getId(), AppConst.SHOP_ROLE_EDIT_INFO);
        Shop shop = this.dispatchContext.getServiceOne(ShopService.class).get(request.getId());
        if (shop == null) return toError(ResponseCode.SHOP_EXISTS);
        long count = this.dispatchContext.getServiceOne(ShopService.class).count(new QueryWrapper().eq("mid", shop.getId()).eq("status", 0));
        if (count > 0) return toError("店铺待审核中,无需再次提交");

        if (StringUtils.isEmpty(request.getLogo())) {
            return toError(ResponseCode.SHOP_APPLY_LOGO_ERR);
        }
        if (StringUtils.isEmpty(request.getName()) || StringUtils.length(request.getName()) < 4) {
            return toError(ResponseCode.SHOP_APPLY_NAME_ERR);
        }
        if (StringUtils.isEmpty(request.getMobile())) {
            return toError(ResponseCode.SHOP_APPLY_MOBILE_ERR);
        }
        if (request.getCid() == 0) return toError(ResponseCode.SHOP_APPLY_CID_ERR);

        if (StringUtils.isEmpty(request.getAddress()) || request.getStateId() == null || request.getCityId() == 0 || request.getDistrictId() == null)
            return toError(ResponseCode.SHOP_APPLY_ADDRESS_ERR);
        Shop copy = request.copy(new Shop());
        copy.setUid(shop.getUid());
        copy.setId(null);
        copy.setMid(shop.getId());
        copy.setType(10);
        copy.setStatus(0);
        copy.setThumbs(StringUtils.join(request.getImages(), ","));
        copy.setLicensePics(StringUtils.join(request.getLicenses(), ","));
        this.dispatchContext.getServiceOne(ShopService.class).save(copy);

        JSONObject other = request.getOther();
        if (other != null && !other.isEmpty()) {
            List<ParamsData> paramsData = other.keySet().stream().map(e -> {
                ParamsData data = new ParamsData();
                data.setKeyword(e);
                data.setValue(other.getString(e));
                data.setRemark("自定义数据");
                return data;
            }).collect(Collectors.toList());
            this.dispatchContext.getServiceOne(IParamsService.class).putParams(copy.getId(), paramsData);
        }
        return toSuccess();
    }


}
